package com.lesgens.blindr.network;
import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import android.os.AsyncTask;
import android.util.JsonReader;
import android.util.Log;
import com.checkin.avatargenerator.AvatarGenerator;
import com.lesgens.blindr.controllers.Controller;
import com.lesgens.blindr.db.DatabaseHelper;
import com.lesgens.blindr.listeners.EventsListener;
import com.lesgens.blindr.listeners.FacebookProfileListener;
import com.lesgens.blindr.listeners.UserAuthenticatedListener;
import com.lesgens.blindr.models.City;
import com.lesgens.blindr.models.Event;
import com.lesgens.blindr.models.Match;
import com.lesgens.blindr.models.User;
import com.lesgens.blindr.network.HTTPRequest.RequestType;
public class Server {
private static List<UserAuthenticatedListener> userAuthenticatedListeners = new ArrayList<UserAuthenticatedListener>();
private static List<EventsListener> eventsListeners = new ArrayList<EventsListener>();
private static List<FacebookProfileListener> profileListeners = new ArrayList<FacebookProfileListener>();
private static String address = "https://blindr-backend.herokuapp.com/";
private static String TAG = "Blindr_Server";
public static void connect(String authenticationToken) {
AsyncTask<String, Void, String> request = new AsyncTask<String, Void, String>() {
@Override
protected String doInBackground(String... arg0) {
String finalAddress = address + "auth";
Log.i(TAG, "auth address: " + finalAddress);
List<NameValuePair> data = new ArrayList<NameValuePair>();
data.add(new BasicNameValuePair("fb_token", arg0[0]));
Log.i(TAG, "fb_token: " + arg0[0]);
HTTPRequest request = new HTTPRequest(finalAddress, RequestType.POST, data);
return request.getOutput();
}
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
String userId = "";
String fakeName = "";
Log.i(TAG, "Auth response's json: "+ result);
try {
String[] auth = readAuth(new StringReader(result));
userId = auth[0];
fakeName = auth[1];
Log.i(TAG, "Auth response's userId: "+ userId + " fake name:" + fakeName);
Controller.getInstance().setMyOwnUser(new User(fakeName, AvatarGenerator.generate(Controller.getInstance().getDimensionAvatar(), Controller.getInstance().getDimensionAvatar()), userId));
for(UserAuthenticatedListener listener: userAuthenticatedListeners) {
listener.onUserAuthenticated();
}
} catch(IOException ioe){
ioe.printStackTrace();
for(UserAuthenticatedListener listener: userAuthenticatedListeners) {
listener.onUserServerErrorAuthentication();
}
} catch (Exception e) {
Log.i(TAG, "Something went wrong while authenticating.");
e.printStackTrace();
for(UserAuthenticatedListener listener: userAuthenticatedListeners) {
listener.onUserNetworkErrorAuthentication();
}
}
}
};
request.execute(authenticationToken);
}
public static void getEvents() {
AsyncTask<String, Void, String> request = new AsyncTask<String, Void, String>() {
@Override
protected String doInBackground(String... arg0) {
String finalAddress = address + "events";
Log.i(TAG, "Events address: " + finalAddress);
Log.i("SERVER+INFOS", "Events city: " + arg0[1]);
List<NameValuePair> data = new ArrayList<NameValuePair>();
data.add(new BasicNameValuePair("city", arg0[1]));
List<NameValuePair> headers = new ArrayList<NameValuePair>();
headers.add(new BasicNameValuePair("X-User-Token", arg0[0]));
HTTPRequest request = new HTTPRequest(finalAddress, RequestType.GET, data, headers);
return request.getOutput();
}
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
List<Event> events = null;
Log.i(TAG, "Events response's json: "+ result);
try {
events = readEvents(new StringReader(result));
for(EventsListener listener:eventsListeners){
listener.onEventsReceived(events);
}
} catch (IOException e) {
Log.i(TAG, "Error while receiving events: ");
e.printStackTrace();
} catch (Exception e) {
Log.i(TAG, "Something went wrong when fetching the events.");
e.printStackTrace();
}
}
};
request.execute(Controller.getInstance().getMyself().getId(), Controller.getInstance().getCity().getName());
}
public static void sendPrivateMessage(User destination, String message) {
AsyncTask<String, Void, String> request = new AsyncTask<String, Void, String>() {
@Override
protected String doInBackground(String... arg0) {
String finalAddress = address + "events/message";
Log.i(TAG, "Send private message address: " + finalAddress);
List<NameValuePair> data = new ArrayList<NameValuePair>();
data.add(new BasicNameValuePair("dst_user", arg0[1]));
data.add(new BasicNameValuePair("message", arg0[2]));
List<NameValuePair> headers = new ArrayList<NameValuePair>();
headers.add(new BasicNameValuePair("X-User-Token", arg0[0]));
HTTPRequest request = new HTTPRequest(finalAddress, RequestType.POST, data, headers);
return request.getOutput();
}
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
Log.i(TAG, "Sent message's response: "+ result);
}
};
request.execute(Controller.getInstance().getMyself().getId(), destination.getId(), message);
}
public static void sendPublicMessage(City destination, String message) {
AsyncTask<String, Void, String> request = new AsyncTask<String, Void, String>() {
@Override
protected String doInBackground(String... arg0) {
String finalAddress = address + "events/message";
Log.i(TAG, "Send public message address: " + finalAddress);
List<NameValuePair> data = new ArrayList<NameValuePair>();
data.add(new BasicNameValuePair("dst_city", arg0[1]));
data.add(new BasicNameValuePair("message", arg0[2]));
List<NameValuePair> headers = new ArrayList<NameValuePair>();
headers.add(new BasicNameValuePair("X-User-Token", arg0[0]));
HTTPRequest request = new HTTPRequest(finalAddress, RequestType.POST, data, headers);
return request.getOutput();
}
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
Log.i(TAG, "Sent message's response: "+ result);
}
};
request.execute(Controller.getInstance().getMyself().getId(), destination.getId(), message);
}
public static void like(User user, String userFakeName) {
AsyncTask<String, Void, String> request = new AsyncTask<String, Void, String>() {
@Override
protected String doInBackground(String... arg0) {
String finalAddress = address + "events/like";
Log.i(TAG, "Like address: " + finalAddress);
List<NameValuePair> data = new ArrayList<NameValuePair>();
data.add(new BasicNameValuePair("dst_user", arg0[1]));
List<NameValuePair> headers = new ArrayList<NameValuePair>();
headers.add(new BasicNameValuePair("X-User-Token", arg0[0]));
HTTPRequest request = new HTTPRequest(finalAddress, RequestType.POST, data, headers);
return request.getOutput();
}
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
Log.i(TAG, "Like's response: "+ result);
}
};
request.execute(Controller.getInstance().getMyself().getId(), user.getId());
for(EventsListener listener: eventsListeners) {
listener.onUserLiked(user, userFakeName);
}
}
public static void dislike(User user) {
AsyncTask<String, Void, String> request = new AsyncTask<String, Void, String>() {
@Override
protected String doInBackground(String... arg0) {
String finalAddress = address + "events/dislike";
Log.i(TAG, "Like address: " + finalAddress);
List<NameValuePair> data = new ArrayList<NameValuePair>();
data.add(new BasicNameValuePair("dst_user", arg0[1]));
List<NameValuePair> headers = new ArrayList<NameValuePair>();
headers.add(new BasicNameValuePair("X-User-Token", arg0[0]));
HTTPRequest request = new HTTPRequest(finalAddress, RequestType.POST, data, headers);
return request.getOutput();
}
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
Log.i(TAG, "Dislike response: "+ result);
}
};
request.execute(Controller.getInstance().getMyself().getId(), user.getId());
}
public static void getMatches() {
// get tous les matchs déjà fait
AsyncTask<String, Void, String> request = new AsyncTask<String, Void, String>() {
@Override
protected String doInBackground(String... arg0) {
String finalAddress = address + "events/like";
Log.i(TAG, "Like address: " + finalAddress);
List<NameValuePair> headers = new ArrayList<NameValuePair>();
headers.add(new BasicNameValuePair("X-User-Token", arg0[0]));
HTTPRequest request = new HTTPRequest(finalAddress, RequestType.GET, null, headers);
return request.getOutput();
}
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
try {
Log.i(TAG, "Matches's response: "+ result);
List<Match> matches = readMatches(new StringReader(result));
for(EventsListener listener: eventsListeners) {
listener.onOldMatchesReceives(matches);
}
} catch (IOException e) {
Log.i(TAG, "Something went wrong when fetching the old matches.");
e.printStackTrace();
} catch (Exception e) {
Log.i(TAG, "Something went wrong when fetching the old matches.");
e.printStackTrace();
}
}
};
request.execute(Controller.getInstance().getMyself().getId());
}
public static void getUserEvents(User user) {
// get les events avec un user en particulier
AsyncTask<String, Void, String> request = new AsyncTask<String, Void, String>() {
@Override
protected String doInBackground(String... arg0) {
String finalAddress = address + "events/" + arg0[1];
Log.i(TAG, "Events avec user address: " + finalAddress);
List<NameValuePair> headers = new ArrayList<NameValuePair>();
headers.add(new BasicNameValuePair("X-User-Token", arg0[0]));
List<NameValuePair> data = new ArrayList<NameValuePair>();
long lastTime = DatabaseHelper.getInstance().getLastMessageFetched(arg0[1]);
Log.i(TAG, "Last message fetched=" + lastTime);
data.add(new BasicNameValuePair("since", String.valueOf(lastTime)));
HTTPRequest request = new HTTPRequest(finalAddress, RequestType.GET, data, headers);
return request.getOutput();
}
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
try {
Log.i(TAG, "User events response: "+ result);
List<Event> events = readEvents(new StringReader(result));
for(EventsListener listener: eventsListeners) {
listener.onUserHistoryReceived(events);
}
} catch (IOException e) {
Log.i(TAG, "Something went wrong when fetching the old matches.");
e.printStackTrace();
} catch (Exception e) {
Log.i(TAG, "Something went wrong when fetching the old matches.");
e.printStackTrace();
}
}
};
request.execute(Controller.getInstance().getMyself().getId(), user.getId());
}
public static void getUserFacebookPictureSlideshow(User user) {
// get les events avec un user en particulier
AsyncTask<String, Void, String> request = new AsyncTask<String, Void, String>() {
@Override
protected String doInBackground(String... arg0) {
String finalAddress = address + "pictures";
Log.i(TAG, "Pictures avec user address: " + finalAddress);
List<NameValuePair> headers = new ArrayList<NameValuePair>();
headers.add(new BasicNameValuePair("X-User-Token", arg0[0]));
List<NameValuePair> data = new ArrayList<NameValuePair>();
data.add(new BasicNameValuePair("dst_id", arg0[1]));
HTTPRequest request = new HTTPRequest(finalAddress, RequestType.GET, data, headers);
return request.getOutput();
}
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
try {
Log.i(TAG, "User pictures response: "+ result);
List<String> pictures = new ArrayList<String>();
StringReader in = new StringReader(result);
JsonReader reader = new JsonReader(in);
reader.beginArray();
while(reader.hasNext()){
for(String s :reader.nextString().split(",")){
pictures.add(s);
}
}
reader.endArray();
reader.close();
in.close();
for(FacebookProfileListener listener: profileListeners) {
listener.onSlideshowPicturesReceived(pictures);
}
} catch (IOException e) {
Log.i(TAG, "Something went wrong when fetching the pictures.");
e.printStackTrace();
} catch (Exception e) {
Log.i(TAG, "Something went wrong when fetching the pictures.");
e.printStackTrace();
}
}
};
request.execute(Controller.getInstance().getMyself().getId(), user.getId());
}
public static void setFacebookUrls(String facebookUrls) {
AsyncTask<String, Void, String> request = new AsyncTask<String, Void, String>() {
@Override
protected String doInBackground(String... arg0) {
String finalAddress = address + "pictures";
Log.i(TAG, "Set facebook urls address: " + finalAddress);
List<NameValuePair> data = new ArrayList<NameValuePair>();
data.add(new BasicNameValuePair("facebookUrls", arg0[1]));
List<NameValuePair> headers = new ArrayList<NameValuePair>();
headers.add(new BasicNameValuePair("X-User-Token", arg0[0]));
HTTPRequest request = new HTTPRequest(finalAddress, RequestType.POST, data, headers);
return request.getOutput();
}
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
Log.i(TAG, "Set facebook urls response: "+ result);
}
};
request.execute(Controller.getInstance().getMyself().getId(), facebookUrls);
}
public static void setInterestedIn(String interests) {
AsyncTask<String, Void, String> request = new AsyncTask<String, Void, String>() {
@Override
protected String doInBackground(String... arg0) {
String finalAddress = address + "interests";
Log.i(TAG, "Set interests address: " + finalAddress);
List<NameValuePair> data = new ArrayList<NameValuePair>();
data.add(new BasicNameValuePair("interested_in", arg0[1]));
List<NameValuePair> headers = new ArrayList<NameValuePair>();
headers.add(new BasicNameValuePair("X-User-Token", arg0[0]));
HTTPRequest request = new HTTPRequest(finalAddress, RequestType.POST, data, headers);
return request.getOutput();
}
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
Log.i(TAG, "Set interests response: "+ result);
}
};
request.execute(Controller.getInstance().getMyself().getId(), interests);
}
public static void addUserAuthenticatedListener(UserAuthenticatedListener listener) {
userAuthenticatedListeners.add(listener);
}
public static void removeUserAuthenticatedListener(UserAuthenticatedListener listener) {
userAuthenticatedListeners.remove(listener);
}
public static void addEventsListener(EventsListener listener) {
eventsListeners.add(listener);
}
public static void removeEventsListener(EventsListener listener) {
eventsListeners.remove(listener);
}
public static void addProfileListener(FacebookProfileListener listener) {
profileListeners.add(listener);
}
public static void removeProfileListener(FacebookProfileListener listener) {
profileListeners.remove(listener);
}
private static String[] readAuth(Reader in) throws IOException {
String[] auth = new String[2];
JsonReader reader = new JsonReader(in);
reader.beginObject();
while(reader.hasNext()){
String name = reader.nextName();
if (name.equals("token")) {
auth[0] = reader.nextString();
} else if (name.equals("fake_name")) {
auth[1] = reader.nextString();
}
}
reader.endObject();
reader.close();
return auth;
}
private static ArrayList<Event> readEvents(Reader in) throws IOException{
ArrayList<Event> events = new ArrayList<Event>();
JsonReader reader = new JsonReader(in);
reader.beginArray();
while (reader.hasNext()) {
events.add(readEvent(reader));
}
reader.endArray();
reader.close();
return events;
}
private static Event readEvent(JsonReader reader) throws IOException {
UUID id = null;
String type = null;
String destination = null;
Timestamp timestamp = null;
String userId = null;
String message = null;
String gender = null;
String fakeName = null;
String realName = null;
reader.beginObject();
while(reader.hasNext()) {
String name = reader.nextName();
if (name.equals("event_id")) {
id = UUID.fromString(reader.nextString());
} else if (name.equals("type")) {
type = reader.nextString();
} else if (name.equals("dst")) {
destination = reader.nextString();
} else if (name.equals("sent_at")) {
timestamp = new Timestamp((long)(reader.nextDouble()*1000));
} else if (name.equals("src")) {
userId = reader.nextString();
} else if (name.equals("message")) {
message = reader.nextString();
} else if(name.equals("src_gender")) {
gender = reader.nextString();
} else if(name.equals("src_fake_name")) {
fakeName = reader.nextString();
} else if(name.equals("src_real_name")) {
realName = reader.nextString();
}else {
reader.skipValue();
}
}
reader.endObject();
return EventBuilder.buildEvent(id, type, destination, timestamp, userId, message, gender, fakeName, realName);
}
private static List<Match> readMatches(Reader in) throws IOException {
List<Match> matches = new ArrayList<Match>();
JsonReader reader = new JsonReader(in);
reader.beginArray();
while(reader.hasNext()) {
matches.add(readMatch(reader));
}
reader.endArray();
reader.close();
return matches;
}
private static Match readMatch(JsonReader reader) throws IOException {
reader.beginObject();
String userId = "";
String fakeName = "";
String realName = "";
Boolean mutual = false;
while(reader.hasNext()) {
String name = reader.nextName();
if(name.equals("other")) {
userId = reader.nextString();
}
else if(name.equals("other_fake_name")) {
fakeName = reader.nextString();
}
else if(name.equals("other_real_name")) {
realName = reader.nextString();
}
else if(name.equals("mutual")) {
mutual = reader.nextBoolean();
}
else {
reader.skipValue();
}
}
reader.endObject();
User user = Controller.getInstance().getUser(userId);
if(user != null) {
return new Match(null, null, Controller.getInstance().getMyself(), user, mutual, realName, fakeName);
}
return null;
}
}